#ifndef _dirsr_h_
#define _dirsr_h_

#include <windows.h>
#include <string>
#include <iostream>
#include <vector>
//#include <fout.h>
using namespace std;


class dirsearch {
class dirdata { public: unsigned int oya; wstring name; };
vector<dirdata*> p;
wstring path, rootpath;
WIN32_FIND_DATAW fd; 
HANDLE hd; 
unsigned int oya, iti; char flg;
public:
wstring filename;
wstring filepath;
unsigned int filesize;
dirsearch(){ }
~dirsearch(){ close(); }

dirsearch(wstring str){ fullpathset(str); open(); }
dirsearch(string str){ fullpathset_c(str);open(); }

void fullpathset_c(string str){  
int m=str.size(); 
wstring wstr(m, '\0'); 
m=MultiByteToWideChar(CP_ACP, 0, &str[0], m, &wstr[0], m); 
wstr.resize(m);  fullpathset(wstr);   }
int open();
void fullpathset( wstring fn);
void close();
void clear(){ close(); open(); }
dirdata& operator [] ( unsigned int n ) { return *p[0]; }

int next(); };


void dirsearch::fullpathset( wstring fn) {
if((int)fn.find(L":")==-1){ 
wstring curr(1<<15,L'\0'); 
int n=GetCurrentDirectoryW(1<<15,&curr[0]); 
curr.resize(n); fn=curr+L"\\"+fn; }
rootpath.resize(1<<16);
wstring tmp; tmp.reserve(1<<16);
tmp= L"\\\\\?\\" +  fn +  L"\\";
unsigned int n=GetFullPathNameW( &tmp[0], 1<<16, &rootpath[0], NULL)-1;
rootpath.resize(n); }


void dirsearch::close(){
unsigned int n; 
for(n=0; n<p.size(); n++) delete p[n];
p.resize(0); }
//
int dirsearch::open() { 
close();
dirdata *x=new dirdata; 
x->oya=-1; x->name=rootpath;
p.push_back(x); flg=0; 
return 1; }
//
int dirsearch::next(){ 
unsigned int k;
dirdata *x;
if(flg) goto erd;
path.resize(1<<16);
for(oya=0; oya<p.size(); oya++) {
k=oya; 
iti=1<<15; 
path[iti]=0; 
iti--; 
path[iti]=L'*';
do { 
x=p[k];
iti--; path[iti]=L'\\';
iti-= x->name.size();  
memcpy( &path[iti], &x->name[0] , 2 * (x->name.size()) );
k=x->oya; } while((int)k!=-1);
hd = FindFirstFileW( &path[iti], &fd );
if(hd==INVALID_HANDLE_VALUE) continue; 
path[(1<<15)-1]=0;
do { 
filename=fd.cFileName;
if ( !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {  
filepath=&path[iti+4]; filesize=fd.nFileSizeLow; 
//static wstring s; s.resize(2); memcpy(&s[0], &oya, 4); s+=filename;
flg=1; return 1;  }
else 
if( filename[0]!=L'.' || ( filename[1]!=L'.' && filename[1]!=L'\0') ) {
x=new dirdata; 
x->oya=oya; 
x->name=filename;
p.push_back(x); }
erd:;
} while(FindNextFileW(hd, &fd));
FindClose(hd);
}
return 0; 
}

#endif